<template>
  <div class="function-line">
    <!-- <div class="input-box">
      <div>
        <div>
          <p>f(x)=</p>
          <p>(js代码)</p>
        </div>
      </div>
      <el-input v-model="functionText" type="textarea" />
      <el-button @click="resetChart">运行</el-button>
      <el-input v-model="functionName" />
      <el-button @click="resetChart">添加</el-button>
    </div> -->
    <el-form class="input-setting" label-width="100px">
      <el-form-item label="f(x)=(js代码)">
        <el-input v-model="functionText" type="textarea" />
      </el-form-item>
      <el-form-item label="函数名称">
        <el-input v-model="functionName" />
      </el-form-item>
      <el-form-item label="最大值">
        <el-input-number v-model="max" :min="0" />
      </el-form-item>
      <el-form-item label="最小值">
        <el-input-number v-model="min" :max="-1" />
      </el-form-item>
      <el-form-item label="间隔值">
        <el-input-number v-model="interval" :step="0.01" />
      </el-form-item>
      <el-form-item label="是否平滑">
        <el-switch v-model="smooth"></el-switch>
      </el-form-item>
      <el-form-item label="">
        <el-button @click="initChart">运行</el-button>
        <el-button @click="addChart">添加</el-button>
        <el-button @click="boom">boom</el-button>
      </el-form-item>
    </el-form>
    <div class="chart" ref="chart"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import chartTheme from "../chartTheme";
export default {
  setup() {
    return { lineChart: {} };
  },
  computed: {
    theme() {
      return chartTheme[this.$store.state.theme];
    },
  },
  data() {
    return {
      functionText: "return Math.sin(x) * Math.cos(x * 2 + 1) * Math.sin(x * 3 + 2) * 50;",
      windowResize: null,
      max: 20,
      min: -20,
      interval: 0.1,
      smooth: false,
      first: true,
      functionName: "测试图像",
      chartNum: 0,
    };
  },
  methods: {
    boom() {
      this.functionText = `return x`;
      this.initChart();
      for (let i = 2; i < 100; i++) {
        setTimeout(() => {
          this.functionText = `return x*` + i;
          this.addChart();
        }, i * 1000);
      }
    },
    resetChart() {
      const option = this.lineChart.getOption();
      option.series.push({
        name: this.functionName,
        type: "line",
        smooth: this.smooth ? 1 : 0,
        showSymbol: false,
        clip: true,
        data: this.setData(),
      });
      this.lineChart.setOption(option);
    },
    addChart() {
      this.chartNum++;
      const option = this.lineChart.getOption();
      option.series.push({
        name: "(" + this.functionName + ")" + this.chartNum,
        type: "line",
        smooth: this.smooth ? 1 : 0,
        showSymbol: false,
        clip: true,
        data: this.setData(),
      });
      this.lineChart.setOption(option);
    },
    initChart() {
      const dataZoom = [
        {
          type: "inside",
          filterMode: "none",
          yAxisIndex: [0],
        },
        {
          type: "inside",
          filterMode: "none",
          xAxisIndex: [0],
          // startValue: -20,
          // endValue: 20,
        },
        {
          filterMode: "none",
          xAxisIndex: [0],
          // startValue: -20,
          // endValue: 20,
        },
        {
          filterMode: "none",
          yAxisIndex: [0],
        },
      ];
      try {
        dataZoom = this.lineChart.getOption().dataZoom;
      } catch (error) {}
      this.chartNum++;
      const option = {
        animation: false,
        textStyle: this.theme.textStyle,
        grid: {
          top: 30,
          left: 60,
          right: 40,
          bottom: 50,
        },
        tooltip: this.theme.tooltip,
        xAxis: {
          name: "x",
          minorTick: {
            show: true,
          },
          axisLine: {
            show: true,
            lineStyle: this.theme.axisLine.lineStyle,
          },
          minorSplitLine: {
            show: true,
            lineStyle: this.theme.minorSplitLine.lineStyle,
          },
          splitLine: {
            lineStyle: this.theme.splitLine.lineStyle,
            show: true,
          },
        },
        yAxis: {
          name: "y",
          minorTick: {
            show: true,
          },
          axisLine: {
            show: true,
            lineStyle: this.theme.axisLine.lineStyle,
          },
          minorSplitLine: {
            show: true,
            lineStyle: this.theme.minorSplitLine.lineStyle,
          },
          splitLine: {
            lineStyle: this.theme.splitLine.lineStyle,
            show: true,
          },
        },
        dataZoom: dataZoom,
        series: [
          {
            name: "(" + this.functionName + ")" + this.chartNum,
            type: "line",
            smooth: this.smooth ? 1 : 0,
            showSymbol: false,
            clip: true,
            data: this.setData(),
          },
        ],
      };
      option.tooltip.formatter = function (params) {
        let text = "";
        for (let i = 0; i < params.length; i++) {
          const element = params[i];
          let name = element.seriesName;
          name = name.substring(1, name.lastIndexOf(")"));
          text += `${element.marker} ${name} : (x : ${element.data[0]} , y : ${element.data[1]})` + "<br/>";
        }
        return text;
      };
      this.lineChart.setOption(option, true);
    },
    setData() {
      const functionText = this.functionText;
      function func(x) {
        const runText = `((x)=>{${functionText}})(${x})`;
        return window.eval(runText);
      }
      let data = [];
      for (let i = this.min; i <= this.max; i += this.interval) {
        data.push([i.toFixed(8), func(i).toFixed(8)]);
      }
      return data;
    },
    resize() {
      this.lineChart.resize();
    },
  },
  mounted() {
    this.lineChart = echarts.init(this.$refs.chart);
    this.$nextTick(() => {
      this.initChart();
    });
    // this.windowResize = window.addEventListener("resize", this.resize);
    const resizeObserver = new ResizeObserver((entries) => {
      this.resize();
    });
    resizeObserver.observe(this.$refs.chart);
  },
};
</script>

<style lang="scss" scoped>
.function-line {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  // flex-direction: column;
  .input-setting {
    overflow: auto;
  }
  .chart {
    flex: 1;
    overflow: hidden;
  }
}
</style>
<style scoped>
.function-line >>> textarea {
  min-height: 100px !important;
}
</style>
